先建三个module
,分别为Butterknife ButterKnife-Annotions ButterKnife-compiler
,其中butterknife
为Android Module
其余的都是Java Module
。
ButterKnife-Annotions
:提供注解。ButterKnife-compiler
: 依赖ButterKnife-Annotions
,生成代码的module
。Butterknife
:应用直接使用的库。
Butterknife-Annotions
添加注解1
2
3
4
5 (CLASS)
(FIELD)
public BindView {
int value();
}
ButterKnife-compiler
添加依赖
1 | dependencies { |
写一个生成代码的类ButterKnifeProcessor
继承AbstractProcessor
1
2
3
4
5
6public class ButterKnifeProcessor extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return false;
}
}
我们的步骤是:
- 添加注解
@AutoService(Processor.class)
- 确定好我们需要生成代码的JAVA版本
- 确定生成代码
- 生成代码
1 | import com.zzw.butterknife_annotions.BindView; |
我们确定一下这个环境编译是否是正确的Butterknife
里面添加ButterKnife-compiler
依赖1
api project(':ButterKnife-compiler')
app
添加Butterknife
依赖和compiler
生成代码依赖
1 | implementation project(':Butterknife') |
在app
的MainActivity
添加注解1
2
3
(R.id.text_view)
TextView textView;
这个时候运行程序报错了提示1
2
3
4
5
6
7
8
9
10
11C:\Users\Swartz\Desktop\githubdemo\AptDemo\ButterKnife-compiler\src\main\java\com\zzw\butterknife_compiler\ButterKnifeProcessor.java
Error:(21, 20) 错误: 编码GBK的不可映射字符
Error:(25, 12) 错误: 编码GBK的不可映射字符
Error:(25, 17) 错误: 编码GBK的不可映射字符
Error:(29, 20) 错误: 编码GBK的不可映射字符
Error:(39, 20) 错误: 编码GBK的不可映射字符
Error:Execution failed for task ':Butterknife:javaPreCompileDebug'.
> Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor. Please add them to the annotationProcessor configuration.
- ButterKnife-compiler.jar (project :ButterKnife-compiler)
Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior. Note that this option is deprecated and will be removed in the future.
See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.
这个是因为我们在ButterKnifeProcessor
这个类使用了中文,所以我们在ButterKnife-compiler
中指定编码集1
2
3tasks.withType(JavaCompile){
options.encoding='UTF-8'
}
这个时候我们在ButterKnifeProcessor
里面process
函数添加打印1
System.out.print("11111");
然后随便修改一下MainActivity
的代码,重新编译在Gradle Console
里面就可以看到打印了。这里需要修改MainActivity
代码是因为我们是编译时生成,as
为了节省时间是重新编译修改了的类,如果不修改的话可以能会不编译。
环境ok了,这下我们就需要重点放在生成代码这块了,这块又分为以下步骤:
- 因为这
getSupportedAnnotationTypes
添加的所有注解都会走到process函数,所以我们要将注解按照类来分离。比如AActivity对应那些有那些注解,BActivity里面有那些注解。- 生成代码
1 |
|
生成的代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// butterknife 自动生成
package com.zzw.app;
import com.zzw.butterknife.Unbinder;
import com.zzw.butterknife.Utils;
import java.lang.Override;
public final class MainActivity_ViewBinding implements Unbinder {
private MainActivity target;
public MainActivity_ViewBinding(MainActivity target) {
this.target = target;
target.textView1 = Utils.findViewById(target,2131165301);
target.textView2 = Utils.findViewById(target,2131165302);
}
public void unbind() {
MainActivity target = this.target;
if (target == null) throw new IllegalStateException("Bindings already cleared.");;
target.textView1 = null;
target.textView2 = null;
}
}
我们可以自动生成代码了,这个时候我们可以通过这个来实现findViewById
我们在Butterknife
module
里面建Butterknife
这个类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.zzw.butterknife;
import android.app.Activity;
import java.lang.reflect.Constructor;
/**
* Des:
* Created by zzw on 2018/1/29.
*/
public class Butterknife {
public static Unbinder bind(Activity activity){
//xxxActivity_ViewBinding viewBinding = new xxxActivity_ViewBinding(activity);
try{
Class<? extends Unbinder> bindClass= (Class<? extends Unbinder>) Class.forName(activity.getClass().getName()+"_ViewBinding");
Constructor<? extends Unbinder> bindConstructor= bindClass.getDeclaredConstructor(activity.getClass());
return bindConstructor.newInstance(activity);
}catch (Exception e){
e.printStackTrace();
return Unbinder.EMPTY;
}
}
}
MainActivity1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36package com.zzw.app;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.zzw.aptdemo.R;
import com.zzw.butterknife.Butterknife;
import com.zzw.butterknife.Unbinder;
import com.zzw.butterknife_annotions.BindView;
public class MainActivity extends AppCompatActivity {
(R.id.text_view1)
TextView textView1;
(R.id.text_view2)
TextView textView2;
private Unbinder mUnbinder;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUnbinder = Butterknife.bind(this);
textView1.setText("你好 大哥");
}
protected void onDestroy() {
super.onDestroy();
mUnbinder.unbind();
}
}
该文中Butterknife module
用到的类:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import android.support.annotation.UiThread;
/**
* Des:
* Created by zzw on 2018/1/29.
*/
public interface Unbinder {
void unbind();
Unbinder EMPTY = new Unbinder() {
public void unbind() { }
};
}
1 | package com.zzw.butterknife; |